package repository

import (
	"gorm.io/gorm"
	"shop-bean/dto"
	"shop-bean/model"
	"shop-common/utils/queryWrapper"
)

type IUserAddrRepository interface {
	Count(db *gorm.DB, userId string) (count int64, err error)
	Create(db *gorm.DB, entity *model.UserAddr) error
	Updates(db *gorm.DB, addrId uint, entity *model.UserAddr) error
	FindOneUserAddrByUserIdAndAddrId(db *gorm.DB, userId string, addrId uint) (*dto.UserAddrDTO, error)
	FindOneDefaultUserAddr(db *gorm.DB, userId string) (*dto.UserAddrDTO, error)
	Find(db *gorm.DB, pair *queryWrapper.WherePair) ([]*dto.UserAddrDTO, error)
	RemoveDefaultUserAddr(db *gorm.DB, userId string) error
	SetDefaultUserAddr(db *gorm.DB, addrId uint, userId string) error
}

type UserAddrRepository struct {
}

func NewUserAddrRepository() IUserAddrRepository {
	return &UserAddrRepository{}
}

func (r *UserAddrRepository) Count(db *gorm.DB, userId string) (count int64, err error) {
	return count, db.Model(&model.UserAddr{}).Where("user_id = ?", userId).Count(&count).Error
}

func (r *UserAddrRepository) Create(db *gorm.DB, entity *model.UserAddr) error {
	return db.Create(entity).Error
}

func (r *UserAddrRepository) FindByUserId(db *gorm.DB, userId string) (dbUserAddr *model.UserAddr, err error) {
	return dbUserAddr, db.Model(&model.UserAddr{}).Where("user_id = ?", userId).Find(&dbUserAddr).Error
}

func (r *UserAddrRepository) Updates(db *gorm.DB, addrId uint, entity *model.UserAddr) error {
	return db.Model(&model.UserAddr{}).Where("addr_id = ?", addrId).Updates(entity).Error
}

func (r *UserAddrRepository) FindOneUserAddrByUserIdAndAddrId(db *gorm.DB, userId string, addrId uint) (entity *dto.UserAddrDTO, err error) {
	return entity, db.Model(&model.UserAddr{}).
		Where("addr_id = ?", addrId).Where("user_id = ?", userId).
		Find(&entity).Error
}
func (r *UserAddrRepository) FindOneDefaultUserAddr(db *gorm.DB, userId string) (entity *dto.UserAddrDTO, err error) {
	return entity, db.Model(&model.UserAddr{}).
		Where("user_id = ?", userId).
		Find(&entity).Error
}

func (r *UserAddrRepository) Find(db *gorm.DB, pair *queryWrapper.WherePair) (entity []*dto.UserAddrDTO, err error) {
	tx := queryWrapper.ReuseWherePair(db.Model(&model.UserAddr{}), pair)
	return entity, tx.Order("common_addr desc").Order("updated_at desc").Find(&entity).Error
}

func (r *UserAddrRepository) RemoveDefaultUserAddr(db *gorm.DB, userId string) error {
	//update tz_user_addr set common_addr = 0 where user_id = #{userId}
	return db.Model(&model.UserAddr{}).Where("user_id = ?", userId).Update("common_addr", 1).Error
}

func (r *UserAddrRepository) SetDefaultUserAddr(db *gorm.DB, addrId uint, userId string) error {
	//update tz_user_addr set common_addr = 1 where user_id = #{userId} and addr_id = #{addrId}
	return db.Model(&model.UserAddr{}).Where("user_id = ?", userId).Where("addr_id = ?", addrId).Update("common_addr", 2).Error
}
